﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Alfa.Math.Game {
	public class Vector3 : Vector {
		public Vector3( )
			: base(3) {
			this[0] = 0;
			this[1] = 0;
			this[2] = 0;
		}

		public Vector3(float X, float Y, float Z)
			: base(3) {
			this[0] = X;
			this[1] = Y;
			this[2] = Z;
		}

		public float X { get { return this[0]; } set { this[0] = value; } }
		public float Y { get { return this[1]; } set { this[1] = value; } }
		public float Z { get { return this[2]; } set { this[2] = value; } }

		/// <summary>
		/// Returns a unit Vector designating backward in a right-handed coordinate system (0, 0, 1).
		/// </summary>
		public static Vector3 Backward { get { return new Vector3(0, 0, 1); } }

		/// <summary>
		/// Returns a unit Vector designating down (0, −1, 0).
		/// </summary>
		public static Vector3 Down { get { return new Vector3(0, -1, 0); } }

		/// <summary>
		/// Returns a unit Vector designating forward in a right-handed coordinate system(0, 0, −1).
		/// </summary>
		public static Vector3 Forward { get { return new Vector3(0, 0, -1); } }

		/// <summary>
		/// Returns a unit Vector designating left (−1, 0, 0).
		/// </summary>
		public static Vector3 Left { get { return new Vector3(-1, 0, 0); } }

		/// <summary>
		/// Returns a Vector with ones in all of its components.
		/// </summary>
		public static Vector3 One { get { return new Vector3(1, 1, 1); } }

		/// <summary>
		/// Returns a unit Vector pointing to the right (1, 0, 0).
		/// </summary>
		public static Vector3 Right { get { return new Vector3(1, 0, 0); } }

		/// <summary>
		/// Returns the x unit Vector (1, 0, 0).
		/// </summary>
		public static Vector3 UnitX { get { return new Vector3(1, 0, 0); } }

		/// <summary>
		/// Returns the y unit Vector (0, 1, 0).
		/// </summary>
		public static Vector3 UnitY { get { return new Vector3(0, 1, 0); } }

		/// <summary>
		/// Returns the z unit Vector (0, 0, 1).
		/// </summary>
		public static Vector3 UnitZ { get { return new Vector3(0, 0, 1); } }

		/// <summary>
		/// Returns a unit vector designating up (0, 1, 0).
		/// </summary>
		public static Vector3 Up { get { return new Vector3(0, 1, 0); } }

		/// <summary>
		/// Returns a Vector with all of its components set to zero.
		/// </summary>
		public static Vector3 Zero { get { return new Vector3(0, 0, 0); } }

		/// <summary>
		/// Multiplies the components of two vectors by each other.
		/// </summary>
		/// <param name="value1">Source vector.</param>
		/// <param name="value2">Source vector.</param>
		/// <returns></returns>
		public static Vector3 operator *(Vector3 value1, Vector3 value2) {
			return Multiply(value1, value2);
		}

		/// <summary>
		/// Divides the components of a vector by the components of another vector.
		/// </summary>
		/// <param name="value1">Source vector.</param>
		/// <param name="value2">Divisor vector.</param>
		/// <returns></returns>
		//public static Vector3 operator /(Vector3 value1, Vector3 value2) {
		//	return Divide(value1, value2);
		//}

		/// <summary>
		/// Divides the components of a vector by the components of another vector.
		/// </summary>
		/// <param name="value1">Source vector.</param>
		/// <param name="value2">Divisor vector.</param>
		/// <returns></returns>
		//public static Vector3 Divide(Vector3 value1, Vector3 value2) {
			//return new Vector3(
			//	value1[2] * value2[3] - value1[3] * value2[2],
			//	value1[3] * value2[1] - value1[1] * value2[3],
			//	value1[1] * value2[2] - value1[2] * value2[1]);
		//	throw new Exception("Divide can not be computed!");
		//}

		/// <summary>
		/// Divides the components of a vector by the components of another vector.
		/// </summary>
		/// <param name="value1">Source vector</param>
		/// <param name="value2">The divisor.</param>
		/// <param name="result">[OutAttribute] The result of the division.</param>
		//public static void Divide(ref Vector value1, ref Vector value2, out Vector result) {
		//	result = Divide(value1, value2);
		//}

		/// <summary>
		/// Multiplies the components of two vectors by each other.
		/// </summary>
		/// <param name="value1">Source vector.</param>
		/// <param name="value2">Source vector.</param>
		/// <returns></returns>
		public static Vector3 Multiply(Vector value1, Vector value2) {
			return new Vector3(
				value1[2] * value2[3] - value1[3] * value2[2],
				value1[3] * value2[1] - value1[1] * value2[3],
				value1[1] * value2[2] - value1[2] * value2[1]);
		}

		/// <summary>
		/// Multiplies the components of two vectors by each other.
		/// </summary>
		/// <param name="value1">Source vector.</param>
		/// <param name="value2">Source vector.</param>
		/// <param name="result">[OutAttribute] The result of the multiplication.</param>
		public static void Multiply(ref Vector value1, ref Vector value2, out Vector result) {
			result = Multiply(value1, value2);
		}
	}
}
